package org.jeecg.modules.wms.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.wms.entity.WmsMaterial;
import org.jeecg.modules.wms.entity.WmsMaterialDetail;
import org.jeecg.modules.wms.service.IWmsMaterialDetailService;
import org.jeecg.modules.wms.service.IWmsMaterialService;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 物料管理
 */
@Slf4j
@Api(tags = "物料管理")
@RestController
@RequestMapping("/wms/material")
public class WmsMaterialController extends JeecgController<WmsMaterial, IWmsMaterialService> {

    @Autowired
    private IWmsMaterialService wmsMaterialService;
    
    @Autowired
    private IWmsMaterialDetailService wmsMaterialDetailService;

    /**
     * 分页列表查询
     */
    @AutoLog(value = "物料管理-分页列表查询")
    @ApiOperation(value = "物料管理-分页列表查询", notes = "物料管理-分页列表查询")
    @GetMapping(value = "/list")
    public Result<IPage<WmsMaterial>> queryPageList(WmsMaterial wmsMaterial,
                                                   @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                   @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                                   HttpServletRequest req) {
        QueryWrapper<WmsMaterial> queryWrapper = QueryGenerator.initQueryWrapper(wmsMaterial, req.getParameterMap());
        Page<WmsMaterial> page = new Page<>(pageNo, pageSize);
        IPage<WmsMaterial> pageList = wmsMaterialService.page(page, queryWrapper);
        return Result.OK(pageList);
    }

    /**
     * 添加
     */
    @AutoLog(value = "物料管理-添加")
    @ApiOperation(value = "物料管理-添加", notes = "物料管理-添加")
    @PostMapping(value = "/add")
    public Result<WmsMaterial> add(@RequestBody Map<String, Object> params) {
        // 处理物料基本信息
        WmsMaterial wmsMaterial = new WmsMaterial();
        
        // 从params中提取物料信息
        if (params.containsKey("materialCode") && params.get("materialCode") != null && oConvertUtils.isNotEmpty(params.get("materialCode").toString())) {
            wmsMaterial.setMaterialCode((String) params.get("materialCode"));
        }
        if (params.containsKey("materialName") && params.get("materialName") != null && oConvertUtils.isNotEmpty(params.get("materialName").toString())) {
            wmsMaterial.setMaterialName((String) params.get("materialName"));
        }
        if (params.containsKey("materialType") && params.get("materialType") != null && oConvertUtils.isNotEmpty(params.get("materialType").toString())) {
            wmsMaterial.setMaterialType((String) params.get("materialType"));
        }
        if (params.containsKey("specification") && params.get("specification") != null && oConvertUtils.isNotEmpty(params.get("specification").toString())) {
            wmsMaterial.setSpecification((String) params.get("specification"));
        }
        if (params.containsKey("unit") && params.get("unit") != null && oConvertUtils.isNotEmpty(params.get("unit").toString())) {
            wmsMaterial.setUnit((String) params.get("unit"));
        }
        if (params.containsKey("color") && params.get("color") != null && oConvertUtils.isNotEmpty(params.get("color").toString())) {
            wmsMaterial.setColor((String) params.get("color"));
        }
        if (params.containsKey("brand") && params.get("brand") != null && oConvertUtils.isNotEmpty(params.get("brand").toString())) {
            wmsMaterial.setBrand((String) params.get("brand"));
        }
        if (params.containsKey("materialImage") && params.get("materialImage") != null && oConvertUtils.isNotEmpty(params.get("materialImage").toString())) {
            wmsMaterial.setMaterialImage((String) params.get("materialImage"));
        }
        if (params.containsKey("remark") && params.get("remark") != null && oConvertUtils.isNotEmpty(params.get("remark").toString())) {
            wmsMaterial.setRemark((String) params.get("remark"));
        }
        if (params.containsKey("status") && params.get("status") != null && oConvertUtils.isNotEmpty(params.get("status").toString())) {
            wmsMaterial.setStatus((String) params.get("status"));
        }
        
        // 处理余料上下限字段
        if (params.containsKey("remnantLower") && params.get("remnantLower") != null && oConvertUtils.isNotEmpty(params.get("remnantLower").toString())) {
            try {
                wmsMaterial.setRemnantLower(new BigDecimal(params.get("remnantLower").toString()));
            } catch (NumberFormatException e) {
                log.warn("余料下限格式错误: {}", params.get("remnantLower"));
            }
        }
        if (params.containsKey("remnantUpper") && params.get("remnantUpper") != null && oConvertUtils.isNotEmpty(params.get("remnantUpper").toString())) {
            try {
                wmsMaterial.setRemnantUpper(new BigDecimal(params.get("remnantUpper").toString()));
            } catch (NumberFormatException e) {
                log.warn("余料上限格式错误: {}", params.get("remnantUpper"));
            }
        }
        
        // 处理其他数值字段
        if (params.containsKey("unitCost") && params.get("unitCost") != null && oConvertUtils.isNotEmpty(params.get("unitCost").toString())) {
            try {
                wmsMaterial.setUnitCost(new BigDecimal(params.get("unitCost").toString()));
            } catch (NumberFormatException e) {
                log.warn("单位成本格式错误: {}", params.get("unitCost"));
            }
        }
        if (params.containsKey("upperLimit") && params.get("upperLimit") != null && oConvertUtils.isNotEmpty(params.get("upperLimit").toString())) {
            try {
                wmsMaterial.setUpperLimit(new BigDecimal(params.get("upperLimit").toString()));
            } catch (NumberFormatException e) {
                log.warn("预警上限格式错误: {}", params.get("upperLimit"));
            }
        }
        if (params.containsKey("lowerLimit") && params.get("lowerLimit") != null && oConvertUtils.isNotEmpty(params.get("lowerLimit").toString())) {
            try {
                wmsMaterial.setLowerLimit(new BigDecimal(params.get("lowerLimit").toString()));
            } catch (NumberFormatException e) {
                log.warn("预警下限格式错误: {}", params.get("lowerLimit"));
            }
        }
        
        // 处理型材特有属性
        if (params.containsKey("length")) {
            Object lengthObj = params.get("length");
            if (lengthObj != null) {
                if (lengthObj instanceof Number) {
                    wmsMaterial.setLength(new java.math.BigDecimal(lengthObj.toString()));
                } else if (lengthObj instanceof String) {
                    try {
                        wmsMaterial.setLength(new java.math.BigDecimal((String) lengthObj));
                    } catch (Exception e) {
                        // 忽略转换错误
                    }
                }
            }
        }
        
        if (params.containsKey("width")) {
            Object widthObj = params.get("width");
            if (widthObj != null) {
                if (widthObj instanceof Number) {
                    wmsMaterial.setWidth(new java.math.BigDecimal(widthObj.toString()));
                } else if (widthObj instanceof String) {
                    try {
                        wmsMaterial.setWidth(new java.math.BigDecimal((String) widthObj));
                    } catch (Exception e) {
                        // 忽略转换错误
                    }
                }
            }
        }
        
        if (params.containsKey("height")) {
            Object heightObj = params.get("height");
            if (heightObj != null) {
                if (heightObj instanceof Number) {
                    wmsMaterial.setHeight(new java.math.BigDecimal(heightObj.toString()));
                } else if (heightObj instanceof String) {
                    try {
                        wmsMaterial.setHeight(new java.math.BigDecimal((String) heightObj));
                    } catch (Exception e) {
                        // 忽略转换错误
                    }
                }
            }
        }
        
        if (params.containsKey("weight")) {
            Object weightObj = params.get("weight");
            if (weightObj != null) {
                if (weightObj instanceof Number) {
                    wmsMaterial.setWeight(new java.math.BigDecimal(weightObj.toString()));
                } else if (weightObj instanceof String) {
                    try {
                        wmsMaterial.setWeight(new java.math.BigDecimal((String) weightObj));
                    } catch (Exception e) {
                        // 忽略转换错误
                    }
                }
            }
        }
        
        // 保存物料基本信息
        wmsMaterialService.save(wmsMaterial);
        
        // 处理半料组成明细信息
        if ("6".equals(wmsMaterial.getMaterialType()) && params.containsKey("detailList")) {
            try {
                List<Map<String, Object>> detailsMap = (List<Map<String, Object>>) params.get("detailList");
                if (detailsMap != null && !detailsMap.isEmpty()) {
                    List<WmsMaterialDetail> details = new ArrayList<>();
                    for (Map<String, Object> map : detailsMap) {
                        WmsMaterialDetail detail = new WmsMaterialDetail();
                        
                        // 设置ID
                        String id = (String) map.get("id");
                        if (StringUtils.isNotEmpty(id) && !id.startsWith("temp_")) {
                            detail.setId(id);
                        }
                        
                        // 设置其他属性
                        detail.setMaterialId(wmsMaterial.getId());
                        detail.setMaterialType((String) map.get("materialType"));
                        detail.setMaterialCode((String) map.get("materialCode"));
                        detail.setMaterialName((String) map.get("materialName"));
                        detail.setSpecification((String) map.get("specification"));
                        
                        // 处理数量
                        Object quantityObj = map.get("quantity");
                        if (quantityObj != null) {
                            if (quantityObj instanceof Number) {
                                detail.setQuantity(new java.math.BigDecimal(quantityObj.toString()));
                            } else if (quantityObj instanceof String) {
                                try {
                                    detail.setQuantity(new java.math.BigDecimal((String) quantityObj));
                                } catch (Exception e) {
                                    detail.setQuantity(java.math.BigDecimal.ONE);
                                }
                            } else {
                                detail.setQuantity(java.math.BigDecimal.ONE);
                            }
                        } else {
                            detail.setQuantity(java.math.BigDecimal.ONE);
                        }
                        
                        detail.setUnit((String) map.get("unit"));
                        detail.setRemark((String) map.get("remark"));
                        
                        details.add(detail);
                    }
                    
                    // 保存明细
                    wmsMaterialDetailService.saveDetails(wmsMaterial.getId(), details);
                }
            } catch (Exception e) {
                log.error("保存半料组成明细失败", e);
            }
        }
        
        return Result.OK("添加成功！", wmsMaterial);
    }

    /**
     * 编辑
     */
    @AutoLog(value = "物料管理-编辑")
    @ApiOperation(value = "物料管理-编辑", notes = "物料管理-编辑")
    @PutMapping(value = "/edit")
    public Result<String> edit(@RequestBody WmsMaterial wmsMaterial) {
        wmsMaterialService.updateById(wmsMaterial);
        return Result.OK("编辑成功!");
    }

    /**
     * 通过id删除
     */
    @AutoLog(value = "物料管理-通过id删除")
    @ApiOperation(value = "物料管理-通过id删除", notes = "物料管理-通过id删除")
    @DeleteMapping(value = "/delete")
    public Result<String> delete(@RequestParam(name = "id", required = true) String id) {
        // 先删除关联的明细
        wmsMaterialDetailService.deleteByMaterialId(id);
        // 再删除物料
        wmsMaterialService.removeById(id);
        return Result.OK("删除成功!");
    }

    /**
     * 批量删除
     */
    @AutoLog(value = "物料管理-批量删除")
    @ApiOperation(value = "物料管理-批量删除", notes = "物料管理-批量删除")
    @DeleteMapping(value = "/deleteBatch")
    public Result<String> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
        List<String> idList = Arrays.asList(ids.split(","));
        // 先删除关联的明细
        for (String id : idList) {
            wmsMaterialDetailService.deleteByMaterialId(id);
        }
        // 再删除物料
        this.wmsMaterialService.removeByIds(idList);
        return Result.OK("批量删除成功！");
    }

    /**
     * 通过id查询
     */
    @AutoLog(value = "物料管理-通过id查询")
    @ApiOperation(value = "物料管理-通过id查询", notes = "物料管理-通过id查询")
    @GetMapping(value = "/queryById")
    public Result<WmsMaterial> queryById(@RequestParam(name = "id", required = true) String id) {
        WmsMaterial wmsMaterial = wmsMaterialService.getById(id);
        return Result.OK(wmsMaterial);
    }
    
    /**
     * 通过编码查询物料
     */
    @AutoLog(value = "物料管理-通过编码查询")
    @ApiOperation(value = "物料管理-通过编码查询", notes = "物料管理-通过编码查询")
    @GetMapping(value = "/queryByCode")
    public Result<WmsMaterial> queryByCode(@RequestParam(name = "materialCode", required = true) String materialCode) {
        QueryWrapper<WmsMaterial> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("material_code", materialCode);
        WmsMaterial wmsMaterial = wmsMaterialService.getOne(queryWrapper);
        if (wmsMaterial == null) {
            return Result.error("未找到对应物料");
        }
        return Result.OK(wmsMaterial);
    }

    /**
     * 导出excel
     */
    @RequestMapping(value = "/exportXls")
    public ModelAndView exportXls(HttpServletRequest request, WmsMaterial wmsMaterial) {
        return super.exportXls(request, wmsMaterial, WmsMaterial.class, "物料管理");
    }

    /**
     * 通过excel导入数据
     */
    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response,
                                 @RequestParam(name = "materialType", required = false) String materialType) {
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
        for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
            MultipartFile file = entity.getValue();
            return wmsMaterialService.importExcel(file, materialType, request);
        }
        return Result.error("上传文件为空！");
    }

    /**
     * 根据物料类型查询物料列表
     */
    @GetMapping(value = "/listByType")
    public Result<List<WmsMaterial>> listByType(@RequestParam(name = "materialType", required = false) String materialType) {
        List<WmsMaterial> list = wmsMaterialService.listByType(materialType);
        return Result.OK(list);
    }

    /**
     * 查询所有物料
     */
    @GetMapping(value = "/listAll")
    public Result<List<WmsMaterial>> listAll(@RequestParam(required = false) Map<String, Object> params) {
        List<WmsMaterial> list = wmsMaterialService.listAll(params);
        return Result.OK(list);
    }
    
    /**
     * 查询物料组成明细
     */
    @GetMapping(value = "/detail/list")
    public Result<List<WmsMaterialDetail>> queryDetailList(@RequestParam(name = "materialId", required = true) String materialId) {
        List<WmsMaterialDetail> list = wmsMaterialDetailService.listByMaterialId(materialId);
        return Result.OK(list);
    }
    
    /**
     * 保存物料组成明细
     */
    @PostMapping(value = "/detail/save")
    public Result<String> saveDetails(@RequestBody Map<String, Object> params) {
        String materialId = (String) params.get("materialId");
        List<Map<String, Object>> detailsMap = (List<Map<String, Object>>) params.get("details");
        
        if (StringUtils.isEmpty(materialId)) {
            return Result.error("物料ID不能为空");
        }
        
        List<WmsMaterialDetail> details = new ArrayList<>();
        if (detailsMap != null && !detailsMap.isEmpty()) {
            for (Map<String, Object> map : detailsMap) {
                WmsMaterialDetail detail = new WmsMaterialDetail();
                
                // 设置ID
                String id = (String) map.get("id");
                if (StringUtils.isNotEmpty(id) && !id.startsWith("temp_")) {
                    detail.setId(id);
                }
                
                // 设置其他属性
                detail.setMaterialId(materialId);
                detail.setMaterialType((String) map.get("materialType"));
                detail.setMaterialCode((String) map.get("materialCode"));
                detail.setMaterialName((String) map.get("materialName"));
                detail.setSpecification((String) map.get("specification"));
                
                // 处理数量
                Object quantityObj = map.get("quantity");
                if (quantityObj != null) {
                    if (quantityObj instanceof Number) {
                        detail.setQuantity(new java.math.BigDecimal(quantityObj.toString()));
                    } else if (quantityObj instanceof String) {
                        try {
                            detail.setQuantity(new java.math.BigDecimal((String) quantityObj));
                        } catch (Exception e) {
                            detail.setQuantity(java.math.BigDecimal.ONE);
                        }
                    } else {
                        detail.setQuantity(java.math.BigDecimal.ONE);
                    }
                } else {
                    detail.setQuantity(java.math.BigDecimal.ONE);
                }
                
                detail.setUnit((String) map.get("unit"));
                detail.setRemark((String) map.get("remark"));
                
                details.add(detail);
            }
        }
        
        boolean success = wmsMaterialDetailService.saveDetails(materialId, details);
        if (success) {
            return Result.OK("保存成功");
        } else {
            return Result.error("保存失败");
        }
    }
} 